package indi.simple.pms.util;

import indi.simple.pms.constant.CommonConstant;
import indi.simple.pms.constant.CommonResultConstant;
import indi.simple.pms.entity.viewobject.CommonResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 类
 *
 * @author wanglunhui
 * @since 2021-12-23 18:02:01
 */
@Slf4j
public class ServletUtil {

    public static ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    public static HttpServletRequest getRequest() {
        return getRequestAttributes().getRequest();
    }

    public static void writeResponse(@NotNull InputStream inputStream, @NotNull HttpServletResponse response, @NotNull String contentType, @NotNull boolean isAttachment, @NotNull String fileName){
        try {
            writeResponseFileHeader(response,contentType,isAttachment,fileName);

            IOUtils.copy(inputStream,response.getOutputStream());
        }catch (Exception e1){
            // 上面写了header和buffer，所以都有清除
            response.reset(); // 清除buffer、headers和response code，response.resetBuffer();只清除buffer
            writeResponse(CommonConstant.ERROR_OCCUR+e1.getMessage(),response);
            log.error(e1.getMessage(),e1);
        }finally {
            try {
                inputStream.close();
            }catch (IOException e2){
                response.reset();
                writeResponse(CommonConstant.ERROR_OCCUR+e2.getMessage(),response);
                log.error(e2.getMessage(),e2);
            }
        }
    }

    public static void writeResponse(@NotNull byte[] bytes, @NotNull HttpServletResponse response, @NotNull String contentType, @NotNull boolean isAttachment, @NotNull String fileName){
        try {
            writeResponseFileHeader(response,contentType,isAttachment,fileName);

            IOUtils.write(bytes,response.getOutputStream());
        }catch (Exception e1){
            response.reset();
            writeResponse(CommonConstant.ERROR_OCCUR+e1.getMessage(),response);
            log.error(e1.getMessage(),e1);
        }
    }

    public static void writeResponse(@NotNull String message, @NotNull HttpServletResponse response){
        writeResponse(CommonResultConstant.SUCCESS,message,response);
    }

    public static void writeResponse(@NotNull Integer code, @NotNull String message, @NotNull HttpServletResponse response){
        writeResponse(code,message,null,response);
    }

    public static void writeResponse(@NotNull Integer code, @NotNull String message, @NotNull Object data, @NotNull HttpServletResponse response){
        response.setStatus(HttpStatus.OK.value());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding(CommonConstant.DEFAULT_CHARSET.name());
        CommonResultVO<?> commonResultVO = CommonResultVO.all(code,message,data);
        try (PrintWriter pw=response.getWriter()){
            pw.print(JsonUtil.objectToJson(commonResultVO));
        }catch (IOException e){
            log.error(e.getMessage(),e);
        }
    }

    public static void writeResponseFileHeader(@NotNull HttpServletResponse response, @NotNull String contentType, @NotNull boolean isAttachment, @NotNull String fileName){
        try {
            response.setStatus(HttpStatus.OK.value());
            response.setCharacterEncoding(CommonConstant.DEFAULT_CHARSET.name());
            response.setContentType(contentType);
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, (isAttachment?"attachment;":"")+(StringUtils.isEmpty(fileName)?"":"fileName="+URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())+";"));
            response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
            response.setDateHeader(HttpHeaders.EXPIRES, 0);
        }catch (UnsupportedEncodingException e){
            throw new RuntimeException(e);
        }
    }

}
